package com.kim.client.netty;

import com.kim.client.handler.NettyClientHandler;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executors;


@ApplicationScoped
@Slf4j
public class Client {

    static final String HOST = "127.0.0.1";
    static final int PORT = 10011;


    private Channel channel;


    @PostConstruct
    public void onStart() {
        try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
            executor.submit(() -> {

                EventLoopGroup group = new NioEventLoopGroup();
                try {
                    Bootstrap b = new Bootstrap();
                    b.group(group)
                            .channel(NioSocketChannel.class)
                            .handler(new ChannelInitializer<SocketChannel>() {
                                @Override
                                public void initChannel(SocketChannel ch) throws Exception {
                                    ChannelPipeline p = ch.pipeline();
                                    p.addLast(new StringDecoder());
                                    p.addLast(new StringEncoder());
                                    p.addLast(new NettyClientHandler());
                                }
                            });

                    // Start the client.
                    ChannelFuture f = b.connect(HOST, PORT).sync();
                    log.info("Client connected to server successfully!");
                    String input = "Mila";
                    channel = f.sync().channel();
                    channel.writeAndFlush(input);
                    channel.flush();
                    f.channel().closeFuture().sync();
                } catch (InterruptedException e) {
                    log.info("Server interrupted!!!");
                } finally {
                    group.shutdownGracefully();
                }
            });
        }
    }
}

